Pull-up and Pull-down Resistors
A digital input that is not driven HIGH or LOW is floating. Pull-up and pull-down resistors solve that problem by giving the signal a weak default state while still allowing another device or switch to override it safely.
Learning Objectives
By the end of this lesson, you should be able to explain floating inputs, draw pull-up and pull-down button circuits, calculate current, choose practical resistor values, and debug common symptoms such as false triggers and slow edges.
Floating Inputs
An MCU input has very high impedance. With no defined path to a rail, leakage, nearby switching signals, static charge, or a finger near the board can move the input voltage into the undefined region. The firmware then reads random HIGH and LOW values.
Pull-up Circuit
A pull-up connects the input to VCC through a resistor. A switch or open-drain transistor can pull the node to ground.
layout direction=LR gap=90
V1: Device:Battery_Cell value="VCC" rotate=0
R1: Device:R value="10 k" rotate=0
SW1: Switch:SW_Push value="Button" rotate=0
U1: Connector_Generic:Conn_01x01 value="MCU input"
group SUPPLY label="Default HIGH" direction=TB {
V1 R1
}
group INPUT label="Input node" direction=TB {
SW1 U1
}
V1.+ --> R1.1
V1.- --> global:0V
R1.2 --> local:BTN
U1.1 --> local:BTN
SW1.1 --> local:BTN
SW1.2 --> global:0V
Released button: input is HIGH. Pressed button: input is LOW. This is common because most MCUs include internal pull-ups.
Pull-down Circuit
A pull-down connects the input to ground through a resistor. An external device drives the node HIGH when active.
layout direction=LR gap=90
SRC: Connector_Generic:Conn_01x02 value="Sensor output"
R1: Device:R value="10 k" rotate=0
U1: Connector_Generic:Conn_01x01 value="MCU input"
group DRIVER label="Active HIGH source" direction=TB {
SRC
}
group INPUT label="Default LOW" direction=TB {
U1 R1
}
SRC.1 --> local:SIG
SRC.2 --> global:0V
U1.1 --> local:SIG
R1.1 --> local:SIG
R1.2 --> global:0V
No drive: input is LOW. Active drive: input is HIGH.
Why the Resistor Is Needed
A resistor limits current when the node is forced to the opposite rail.
For a 5 V pull-up with a pressed button:
$$
I = \frac{V}{R} = \frac{5 V}{10 k\Omega} = 0.5 mA
$$
A direct wire from input to VCC would short the supply when the button closed to ground.
Choosing the Value
| Value | Current | Noise immunity | Edge speed | Typical use |
|---|---|---|---|---|
1 kOhm |
higher | strong | fast | noisy cables, faster open-drain edges |
4.7 kOhm |
moderate | good | good | I2C and general external pulls |
10 kOhm |
low | normal | normal | buttons and short GPIO wiring |
47 kOhm to 100 kOhm |
very low | weak | slow | low-power, low-noise environments |
Large resistors save current but are more sensitive to leakage and capacitance. Small resistors improve noise immunity and speed but waste more current when asserted.
RC Speed Limit
The pull resistor and input or cable capacitance form an RC time constant:
$$
\tau = RC
$$
A 10 kOhm pull-up with 100 pF capacitance gives:
$$
\tau = 10,000 \times 100 pF = 1 us
$$
That is fine for a button but may be too slow for a high-speed bus.
Common Mistakes
- Leaving unused CMOS inputs floating.
- Enabling a pull-up but writing firmware as if the button is active HIGH.
- Using internal weak pulls on long noisy cables.
- Forgetting I2C pull-ups.
- Choosing very large values where leakage current is comparable to pull current.
Practical Checks
Measure the released and asserted voltages, confirm the active polarity in firmware, calculate current in the asserted state, estimate RC rise time, and check whether external devices can safely override the pull.
Summary
Pull resistors define a safe default logic state. A pull-up defaults HIGH; a pull-down defaults LOW. The value balances current, noise immunity, leakage, and speed.
Further Reading
- MCU datasheet GPIO input leakage and internal pull resistor specifications.
- NXP, Texas Instruments, and Microchip application notes on I2C pull-up selection.
- Switch debouncing application notes from major MCU vendors.